﻿using Client.Json;
using Client.工具类;
using Client.窗体;
using Microsoft.DirectX.DirectSound;
using RRQMCore.ByteManager;
using RRQMSocket;
using RRQMSocket.FileTransfer;
using Shell32;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Client
{
	public partial class Form1 : Form
    {
        const string cfg = "cfg.ini";
        Config cf;
        string path = "";
        string uid = "未知";
        string mid = "";
        private FileClient fileClient;
        SimpleTcpClient tcpClient = new SimpleTcpClient();
        bool take = false;

        WMPLib.WindowsMediaPlayer wplayer = new WMPLib.WindowsMediaPlayer();
        public Form1()
        {
            InitializeComponent();

            CheckForIllegalCrossThreadCalls = false;
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SimpleTcpClientConnect();
            ConnectService();

        }
        private void ConnectService()
        {
            if (fileClient == null)
            {
                fileClient = new FileClient();
                fileClient.TransferFileError += FileClient_TransferFileError;
                fileClient.BeforeFileTransfer += FileClient_BeforeFileTransfer; ;
                fileClient.FinishedFileTransfer += FileClient_FinishedFileTransfer; ;
                fileClient.DisconnectedService += FileClient_DisConnectedService;
                fileClient.ConnectedService += FileClient_ConnectedService;
                fileClient.FileTransferCollectionChanged += FileClient_FileTransferCollectionChanged;
                fileClient.Received += FileClient_Received;
            }

            try
            {
                var config = new FileClientConfig();
                // config.Logger = new MsgLog(ShowMsg);
                config.RemoteIPHost = new IPHost("127.0.0.1:33006");//服务器地址
                config.VerifyToken = "123ABC";//连接验证令箭
                config.BufferLength = 64 * 1024;//缓存池，该值太小会影响接收效率
                config.PacketSize = 64 * 1024;//包尺寸，当网络比较差时，应该设置小点，最大值不能超过10Mb
                config.DataHandlingAdapter = new FixedHeaderDataHandlingAdapter();//此处允许设置数据处理适配器，但是只能设置固定包头。
                config.ReceiveDirectory = "Received";//此处可以设置默认下载文件目录，但是最终路径受UrlFileInfo.SaveFullPath决定。
                config.Timeout = 10 * 1000;//设置默认单次请求最大等待时间。
                fileClient.Setup(config);
                fileClient.Connect();
            }
            catch (Exception ex)
            {
                if (fileClient != null && fileClient.Online)
                {
                    fileClient.Dispose();
                }

                fileClient = null;
                ShowMsg(ex.Message);
            }
        }
        private void FileClient_FileTransferCollectionChanged(object sender, MesEventArgs e)
        {


        }
        private void FileClient_DisConnectedService(object sender, MesEventArgs e)
        {

        }
        private void FileClient_ConnectedService(object sender, MesEventArgs e)
        {

            this.Text += ",连接文件服务器成功";
        }
        private void FileClient_FinishedFileTransfer(object sender, TransferFileMessageArgs e)
        {
            FileClient fileClient = sender as FileClient;//客户端中事件的sender实例均为FileClient
            UrlFileInfo fileInfo = e.UrlFileInfo;//通过事件参数值，可获得完成的文件信息
            if (e.TransferType == TransferType.Download)
            {
                ShowMsg(string.Format("文件：{0}下载完成", e.UrlFileInfo.FileName));

                label10.Text = "下载完成";
                label9.Text = "已缓存";
                string title = listBox1.SelectedItem.ToString().Split('|')[3] + "." + listBox1.SelectedItem.ToString().Split('|')[4];

                wplayer.URL =  textBox3.Text+title;
                wplayer.controls.play();
                mid = title;

            }
            else
            {
                ShowMsg(string.Format("文件：{0}上传完成", e.UrlFileInfo.FileName));
            }
        }
        private void FileClient_BeforeFileTransfer(object sender, FileOperationEventArgs e)
        {
            if (e.TransferType == TransferType.Download)
            {
                if (!Directory.Exists("ClientReceiveDir"))
                {
                    Directory.CreateDirectory("ClientReceiveDir");
                }

                string Path = textBox3.Text+ e.UrlFileInfo.FileName;

                e.UrlFileInfo.SaveFullPath = Path;
            }
        }

        private void FileClient_TransferFileError(object sender, TransferFileMessageArgs e)
        {
            ShowMsg($"传输类型：{e.TransferType}，信息：{e.Message}");
        }
        private void DisconnectService()
        {
            if (fileClient != null && fileClient.Online)
            {
                fileClient.Dispose();
            }

            fileClient = null;
        }

        private void FileClient_Received(object sender, short? procotol, RRQMCore.ByteManager.ByteBlock byteBlock)
        {
            ShowMsg($"收到：协议={procotol}，信息={Encoding.UTF8.GetString(byteBlock.Buffer, 2, (int)byteBlock.Length - 2)}");
        }
        private bool BeginDownload(string mid)
        {
            if (fileClient != null && fileClient.Online)
            {
                if (string.IsNullOrEmpty(mid))
                {
                    ShowMsg("Url不能为空");
                    return false;
                }

                try
                {
                    TransferFlags transferFlags = new TransferFlags();
                    transferFlags = transferFlags | TransferFlags.BreakpointResume;
                    transferFlags = transferFlags | TransferFlags.QuickTransfer;


                    UrlFileInfo urlFileInfo = UrlFileInfo.CreateDownload(mid, transferFlags);

                    fileClient.RequestTransfer(urlFileInfo);

                    return true;
                }
                catch (Exception e)
                {
                    ShowMsg(e.Message);

                    return false;
                }
            }
            else
            {
                ShowMsg("未连接");

                return false;
            }
        }
        void ShowMsg(string str)
        {
            MessageBox.Show(str);
        }
        private void SimpleTcpClientConnect()
        {

            tcpClient.ConnectedService += (object sender, MesEventArgs e) =>
            {
                //成功连接到服务器
                //sender对象为SimpleTcpClient类型
                SimpleTcpClient client = (SimpleTcpClient)sender;

                this.Text = "连接服务器成功";


            };

            tcpClient.DisconnectedService += (object sender, MesEventArgs e) =>
            {
                //从服务器断开连接，当连接不成功时不会触发。
                //sender对象为SimpleTcpClient类型
                SimpleTcpClient client = (SimpleTcpClient)sender;
                this.Text = "服务器断开";

                label4.Text = "你当前的UID:未知";
                uid = "未知";
            };

            tcpClient.Received += (ByteBlock byteBlock, object arg2) =>
            {
                //客户端接收信息
                string mes = Encoding.UTF8.GetString(byteBlock.Buffer, 0, byteBlock.Len);

               

                var json = JsonHelper.ServerRequest_deserialization(mes);
                string sid = json[0][0];
                string tab = json[1][0];
                string ret = json[2][0];
                string[] arr = json[3];
                switch (tab)
                {
                    case "uinf":

                        MessageBox.Show(ret, sid);
                        label4.Text = "你当前的UID:" + arr[0];
                        uid = arr[0];
                        break;
                    case "sc":

                        switch (ret)
                        {
                            case "mu":
                                Hashtable ht = new Hashtable();
                                List<string> fin = new List<string>();
                                List<string> cin = new List<string>();
                                Dictionary<string, double> dic = new Dictionary<string, double>(new MyDictionaryComparer());
                                ///title
								foreach (var item in arr)
								{
                                    double sim = Sim(item.Split('|')[0], textBox2.Text);
                                    if (sim != 0 )
                                    {
                                        dic.Add(item, sim);
                                    }
								}

								foreach (var item in DictonarySort(dic))
								{
                                    fin.Add(item);

                                }
                                dic.Clear();
                                ///artists
                                ///
                                foreach (var item in arr)
                                {
                                    double sim = Sim(item.Split('|')[1], textBox2.Text);
                                    if (sim != 0)
                                    {
                                        dic.Add(item, sim);
                                    }
                                }
								foreach (var item in DictonarySort(dic))
								{
                                    if (!fin.Exists(t => t == item))
                                        fin.Add(item);
								}


                                ///artists
                                ///
                                foreach (var item in arr)
                                {
                                    double sim = Sim(item.Split('|')[2], textBox2.Text);
                                    if (sim != 0)
                                    {
                                        dic.Add(item, sim);
                                    }
                                }
                                foreach (var item in DictonarySort(dic))
                                {
                                    if (!fin.Exists(t => t == item))
                                        fin.Add(item);
                                }
                                
                                listBox1.Items.AddRange(fin.ToArray());



                                break;

                            default:
                                break;
                        }
                        break;
                    default:
                        break;
                }

                //   MessageBox.Show()
            };

            //声明配置
            var config = new TcpClientConfig();
            config.RemoteIPHost = new IPHost(textBox1.Text);//远程IPHost
            config.BytePool = BytePool.Default;//设置内存池实例。
            config.BufferLength = 1024 * 64;//缓存池容量
            config.BytePoolMaxSize = 512 * 1024 * 1024;//单个线程内存池容量
            config.BytePoolMaxBlockSize = 20 * 1024 * 1024;//单个线程内存块限制
            config.Logger = new Log();//日志记录器，可以自行实现ILog接口。
            config.SeparateThreadReceive = false;//独立线程接收，当为true时可能会发生内存池暴涨的情况
            config.DataHandlingAdapter = new NormalDataHandlingAdapter();//设置数据处理适配器
            config.OnlySend = false;//仅发送，即不开启接收线程，同时不会感知断开操作。
            config.SeparateThreadSend = false;//在异步发送时，使用独立线程发送
            config.SeparateThreadSendBufferLength = 1024 * 1024;// 独立线程发送缓存区长度。

            //载入配置
            tcpClient.Setup(config);


            try
            {
                //连接
                //执行无异常即连接成功
                tcpClient.Connect();
            }
            catch
            {
                //连接异常
            }
        }
        private List<string> DictonarySort(Dictionary<string, double> dic)
        {

            List<string> di = new List<string>();
            var dicSort = from objDic in dic orderby objDic.Value descending select objDic;
            foreach (KeyValuePair<string, double> kvp in dicSort) 
            {
                di.Add(kvp.Key);
            }
            return di;
              //  Response.Write(kvp.Key + "：" + kvp.Value + "<br />");
        }
        public double Sim(string txt1, string txt2)
        {
            List<char> sl1 = txt1.ToCharArray().ToList();
            List<char> sl2 = txt2.ToCharArray().ToList();
            //去重
            List<char> sl = sl1.Union(sl2).ToList<char>();

            //获取重复次数
            List<int> arrA = new List<int>();
            List<int> arrB = new List<int>();
            foreach (var str in sl)
            {
                arrA.Add(sl1.Where(x => x == str).Count());
                arrB.Add(sl2.Where(x => x == str).Count());
            }
            //计算商
            double num = 0;
            //被除数
            double numA = 0;
            double numB = 0;
            for (int i = 0; i < sl.Count; i++)
            {
                num += arrA[i] * arrB[i];
                numA += Math.Pow(arrA[i], 2);
                numB += Math.Pow(arrB[i], 2);
            }
            double cos = num / (Math.Sqrt(numA) * Math.Sqrt(numB));
            Random rt = new Random();

            return cos;
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            cf = new Config(cfg);
            textBox1.Text = cf.get("IP")+":"+cf.get("P1");
            textBox4.Text = cf.get("IP") + ":"+cf.get("P2");
            comboBox1.SelectedIndex = 0;
            wplayer.StatusChange += StatusChange;

        }
        void PositionChange()
        { 

        }
            void StatusChange()
        {
            if (textBox3.Text.LastIndexOf(@"\") != textBox3.Text.Length - 1)
            {
                textBox3.Text += @"\";
            }

            switch (wplayer.playState)
            {
                case WMPLib.WMPPlayState.wmppsPaused:
                    button2.Text = "播放";
                    break;
                case WMPLib.WMPPlayState.wmppsUndefined:
                    break;
                case WMPLib.WMPPlayState.wmppsReady:
                  //  wplayer.controls.play();
                    break;
                case WMPLib.WMPPlayState.wmppsPlaying:
                    button2.Text = "暂停";
                   
                    MPlayer mPlayer = new MPlayer(wplayer.URL);
                    label3.Text = mPlayer.getTitle();
                    label7.Text = mPlayer.getArtists();
                    label8.Text = mPlayer.getAlbum();
                    break;
                case WMPLib.WMPPlayState.wmppsStopped:

                        string title = "";

                        switch (comboBox1.SelectedIndex)
                        {
                            case 0:
                                //单曲循环
                                wplayer.controls.play();
                                break;
                            case 1:
                                if (listBox2.SelectedIndex == listBox2.Items.Count - 1)
                                {
                                    listBox2.SelectedIndex = 0;
                                    title = listBox2.SelectedItem.ToString().Split('|')[3] + "." + listBox2.SelectedItem.ToString().Split('|')[4];
                                    setPlay(title);
                                }
                                else
                                {
                                    listBox2.SelectedIndex++;
                                    title = listBox2.SelectedItem.ToString().Split('|')[3] + "." + listBox2.SelectedItem.ToString().Split('|')[4];
                                    setPlay(title);
                                }
                                //列表循环
                                break;
                            case 2:
                                Random ra = new Random();
                                listBox2.SelectedIndex = ra.Next(0, listBox2.Items.Count - 1);
                                title = listBox2.SelectedItem.ToString().Split('|')[3] + "." + listBox2.SelectedItem.ToString().Split('|')[4];
                                setPlay(title);
                                //随机播放
                                break;
                            default:
                                break;
                        }

                        trackBar1.Value = 0;
                        label2.Text = "00:00";
                        label1.Text = "00:00";
                        button2.Text = "播放";
                    break;

                default:
                    break;
            }
        }
        string setPlay(string title)
        {
            try
            {
                if (listBox1.SelectedItems.Count != 1)

                    return "播放失败，请选择一首歌";

                if (mid != title)
                {
                    //从头开始播放
                    if (!Directory.Exists(textBox3.Text))
                    {
                        return "播放失败，请填写正确的缓存目录";
                    }
                    if (listBox1.SelectedItems.Count == 1)
                    {


                        if (File.Exists(textBox3.Text + title))
                        {
                            //本地已缓存，直接播放本地缓存
                            wplayer.URL=textBox3.Text + title;
                            wplayer.controls.play();
                            mid = title;

                            return "播放成功";
                        }
                        else
                        {
                            //本地无缓存，需要先下载

                            if (BeginDownload(title))
                            {

                                
                                return "下载中";
                            }
                            else 
                            {

                                return "下载失败";
                            }
                        }
                    }
                    else
                    {

                    }

                    button2.Text = "暂停";
                    return "开始播放";


                }
                else 
                {
                    wplayer.controls.play();

                    button2.Text = "暂停";
                    return "取消暂停";
                } 



            }

            catch (Exception e)
            {

                return "播放失败" + e.Message;
            }
        }
        string setPause()
        {
			try
			{
                wplayer.controls.pause();
                button2.Text = "播放";
                return "暂停成功";
            }
			catch (Exception e)
			{

                return "暂停失败"+e.Message;
                throw;
			}
        }
        string setStop()
        {
            wplayer.controls.stop();
            trackBar1.Value = 0;
            return "失败";
        }
        private void button2_Click(object sender, EventArgs e)
        {
            string title = "";
            if (listBox2.SelectedItems.Count == 1)
            {
                title = listBox2.SelectedItem.ToString().Split('|')[3] + "." + listBox2.SelectedItem.ToString().Split('|')[4];
            }
            else 
            {

                title = listBox1.SelectedItem.ToString().Split('|')[3] + "." + listBox1.SelectedItem.ToString().Split('|')[4];
            }
            if (textBox3.Text.LastIndexOf(@"\") != textBox3.Text.Length - 1)
            {
                textBox3.Text += @"\";
            }
            switch (wplayer.playState)
            {
                case WMPLib.WMPPlayState.wmppsPlaying:
                    //播放中，将要暂停
                    label10.Text = setPause();
                    break;
                case WMPLib.WMPPlayState.wmppsStopped:
                    //未播放歌曲，将要播放
                    label10.Text = setPlay(title);
                    break;
                case WMPLib.WMPPlayState.wmppsPaused:
                    //暂停中，将要播放
                    label10.Text = setPlay(title);
                    break;
                case WMPLib.WMPPlayState.wmppsUndefined:

                    //未播放歌曲，将要播放
                    label10.Text = setPlay(title);
                    break;
                case WMPLib.WMPPlayState.wmppsReady:
                    wplayer.controls.play();
                    break;
                default:
                    break;
            }


        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            switch (wplayer.playState)
            {
                case WMPLib.WMPPlayState.wmppsPlaying:

                    var EndPoint = wplayer.currentMedia.duration;
                    if (EndPoint == 0)
                        return;
                    trackBar1.Maximum = (int)wplayer.currentMedia.duration;

                    trackBar1.Value = (int)wplayer.controls.currentPosition;
                    label1.Text = wplayer.controls.currentPositionString;
                    label2.Text = wplayer.currentMedia.durationString;
                    break;

                default:
                    break;
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            
            setStop();
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            /*
            if (trackBar1.Value < 10)
            {
                label1.Text = "00:0" + myplayer.Position;
            }
            else if (trackBar1.Value < 60)
            {

                label1.Text = "00:" + trackBar1.Value;
            }
            else
            {
                int min = trackBar1.Value / 60;
                int s = trackBar1.Value % 60;
                string str = "";
                if (s < 10)
                {
                    str = "0" + s.ToString();
                }
                else
                {
                    str = s.ToString();
                }
                label1.Text = min.ToString() + ":" + str;
            }*/
        }

        private void trackBar1_MouseUp(object sender, MouseEventArgs e)
        {/*
            if (myplayer.State == PlayState.Playing)
            {
                myplayer.Position = trackBar1.Value;
            }
            take = false;*/
        }

        private void trackBar1_MouseDown(object sender, MouseEventArgs e)
        {
            take = true;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            search();
        }
        void search()
        {
            if (tcpClient.Online)

            {
                var json = JsonHelper.ClientRequest_serialization(uid, "sc", "mu", textBox2.Text);
                tcpClient.Send(Encoding.UTF8.GetBytes(json));
            }
        }

		private void button5_Click(object sender, EventArgs e)
		{
            Thread t = new Thread((ThreadStart)(() =>
            {
                FolderBrowserDialog dlg = new FolderBrowserDialog();

                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    textBox3.Text = dlg.SelectedPath.ToString();
                }

            }));
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
            t.Join();
        }

		private void button6_Click(object sender, EventArgs e)
		{
            if (Directory.Exists(textBox3.Text))
                {

                System.Diagnostics.Process.Start(textBox3.Text);
            }
		}

		private void label3_Click(object sender, EventArgs e)
		{

		}

		private void button7_Click(object sender, EventArgs e)
        {
            const string str = @"D:\aaa\a.mp3";

            wplayer.URL = str;
            wplayer.controls.play();
        }

		private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            string title = listBox1.SelectedItem.ToString().Split('|')[3] + "." + listBox1.SelectedItem.ToString().Split('|')[4];
            if (mid == title)
            {
                wplayer.controls.stop();
                wplayer.controls.play();
                return;
            }

            if (textBox3.Text.LastIndexOf(@"\") != textBox3.Text.Length - 1)
            {
                textBox3.Text += @"\";
            }


          //  wplayer.currentPlaylist.a
            if (!listBox2.Items.Contains(listBox1.SelectedItem))
            {
                listBox2.Items.Add(listBox1.SelectedItem);
            }
            listBox2.SelectedItem = listBox1.SelectedItem;
            label10.Text = setPlay(title);
        }

		private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
		{

        }

		private void textBox3_TextChanged(object sender, EventArgs e)
		{

		}

		private void listBox2_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            string title = listBox2.SelectedItem.ToString().Split('|')[3] + "." + listBox2.SelectedItem.ToString().Split('|')[4];
            if (mid == title)
            {
                wplayer.controls.stop();
                wplayer.controls.play();
                return;
            }
            if (textBox3.Text.LastIndexOf(@"\") != textBox3.Text.Length - 1)
            {
                textBox3.Text += @"\";
            }

            label10.Text = setPlay(title);
        }

		private void button8_Click(object sender, EventArgs e)
		{
            listBox2.Items.Clear();
            setStop();
        }

		private void listBox2_SelectedIndexChanged(object sender, EventArgs e)
		{

		}

		private void button7_Click_1(object sender, EventArgs e)
		{
            cf.set("P1", textBox1.Text);
            cf.set("P2", textBox4.Text);
            cf.save();
            MessageBox.Show("保存成功");
        }

		private void textBox2_KeyDown(object sender, KeyEventArgs e)
		{
            if (e.KeyCode == Keys.Enter)
            {

                listBox1.Items.Clear();
                search();
            }
        }
	}
	class UF : Form { }
}
